package com.tcc.util.file;


import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import com.tcc.util.common.StringUtil;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.util.List;
import java.util.Objects;

public class PDFUtilsByMapper {
    private static Font DEFAULT_FONT;

    static {
        try {
            BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            DEFAULT_FONT = new Font(baseFont);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 将table转化成pdf
     *
     * @param file
     * @param title
     * @param font
     * @param imgPath
     * @param headers
     * @param props
     * @param data
     */
    public static <T> void table2PDF(String file, String title, Font font, String imgPath, List<String> headers,
                                     List<String> props, List<T> data) {
        try {

            Document document = new Document(PageSize.A4);
            PdfWriter.getInstance(document, new FileOutputStream(file));

            document.open();

            // 设置字体
            if (font == null) {
                font = DEFAULT_FONT;
            }

            // 添加title
            if (StringUtil.hasText(title)) {
                writeTitle(title, document, font);
            }

            // 写数据
            PdfPTable table = new PdfPTable(headers.size());
            // 写头
            writeHeaders(font, headers, table);
            // 写数据
            writeData(font, props, data, table);

            document.add(table);

            // 图片
            if (StringUtil.hasText(imgPath)) {
                writeImage(imgPath, document);
            }

            document.close();
        } catch (Exception e) {

            System.out.println("pdf生成失败");
            e.printStackTrace();
        }

        System.out.println("PDF生成成功");
    }

    /**
     * pdf转图片
     *
     * @param pdfFile
     * @param pngFile D://test//stu.png stu1.png stu2.png
     * @return
     */
    public static boolean pdf2png(String pdfFile, String pngFile) {
        System.out.println("开始pdf生成png图片");
        try {
            // 加载pdf信息
            PDDocument pdfDocment = PDDocument.load(new File(pdfFile));
            // 获取页数
            int pages = pdfDocment.getNumberOfPages();
            // 获取pdf渲染
            PDFRenderer pdfRenderer = new PDFRenderer(pdfDocment);
            // 循环转化
            for (int i = 0; i < pages; i++) {
                BufferedImage image = pdfRenderer.renderImageWithDPI(i, 144);// page , dpi分辨率单位
                // BufferedImage image = renderer.renderImage(i, 2.5f); // 也可以 page,缩放比
                ImageIO.write(image, "PNG", new File(pngFile));
                //	            ImageIO.write(image, "PNG",
                //	            		new File(new StringBuffer(pngFile).insert(pdfFile.lastIndexOf("."),"_"+i ).toString()));
                System.out.println("生成成功");
            }

        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("转化失败");
            return false;
        }
        return true;
    }

    /**
     * 写入数据
     *
     * @param font
     * @param props
     * @param data
     * @param table
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    private static <T> void writeData(Font font, List<String> props, List<T> data, PdfPTable table)
            throws NoSuchFieldException, IllegalAccessException {
        for (T t : data) {
            for (String prop : props) {
                // 根据具体字段获取实体类中当前字段对应的值
                Field field = t.getClass().getDeclaredField(prop);

                if (Objects.nonNull(field)) {
                    // 设置访问权限 private-》public
                    field.setAccessible(true);
                    // 获取字段对应的值
                    Object value = field.get(t);
                    if (Objects.nonNull(value)) {
                        // 写入
                        table.addCell(new PdfPCell(new Phrase(value.toString(), font)));
                    } else {
                        table.addCell(new PdfPCell(new Phrase("", font)));
                    }
                } else {
                    table.addCell(new PdfPCell(new Phrase("", font)));
                }
            }
        }
    }

    /**
     * 写表格头
     *
     * @param font
     * @param headers
     * @param table
     */
    private static void writeHeaders(Font font, List<String> headers, PdfPTable table) {
        headers.forEach(item -> {
            table.addCell(new PdfPCell(new Phrase(item, font)));

        });
    }

    /**
     * 嵌入图片
     *
     * @param imgPath
     * @param document
     * @throws BadElementException
     * @throws MalformedURLException
     * @throws IOException
     * @throws DocumentException
     */
    private static void writeImage(String imgPath, Document document)
            throws BadElementException, MalformedURLException, IOException, DocumentException {
        // 添加图片
        Image image = Image.getInstance(imgPath);
        image.setAlignment(Image.ALIGN_CENTER);
        image.scalePercent(40);// 依照比例缩放
        document.add(image);
    }

    /**
     * 写标题
     *
     * @param title
     * @param document
     * @param font
     * @throws Exception
     */
    private static void writeTitle(String title, Document document, Font font) throws Exception {
        // 添加段落
        Paragraph paragraph = new Paragraph(title, font);
        paragraph.setAlignment(1); // 设置文字居中 0靠左 1，居中 2，靠右
        paragraph.setIndentationLeft(12); // 设置左缩进
        paragraph.setIndentationRight(12); // 设置右缩进
        paragraph.setFirstLineIndent(24); // 设置首行缩进
        paragraph.setLeading(20f); // 行间距
        paragraph.setSpacingBefore(5f); // 设置段落上空白
        paragraph.setSpacingAfter(10f); // 设置段落下空白
        document.add(paragraph);
    }


    /**
     * 获取字体
     *
     * @param winPath   win下字体路径 D://test//simkai.ttf
     * @param linuxPath linux 下字体路径 /tmp/simkai.ttf
     * @return
     */
    public static Font getFont(String winPath, String linuxPath) {
        String fontPath = System.getProperty("os.name").toLowerCase().contains("windows") ? winPath : linuxPath;

        try {
            return new Font(BaseFont.createFont(fontPath, BaseFont.IDENTITY_H, BaseFont.EMBEDDED));
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("获取失败");
            return DEFAULT_FONT;
        }
    }

}
